package com.itestor.iptv.modules.common.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;

import com.itestor.iptv.modules.common.dao.TbUserDao;
import com.itestor.iptv.modules.common.domain.Child;
import com.itestor.iptv.modules.common.domain.Father;
import com.itestor.iptv.modules.common.domain.RoleGroup;
import com.itestor.iptv.modules.common.domain.UserAccount;
import com.itestor.iptv.modules.common.domain.UserRoleGroup;
import com.itestor.iptv.modules.common.service.UserService;
import com.itestor.iptv.modules.common.vo.User;
import com.itestor.iptv.modules.common.vo.UserQuery;
import com.itestor.iptv.utils.BeanConverter;

/**
 * 
 * @author Mr.li
 * 
 */
public class UserServiceImpl implements UserService {

    private static final Logger logger = Logger
            .getLogger(UserServiceImpl.class);

    private TbUserDao tbUserDao;

    private Map<String, String> roleMap;

    public User get(String username) {
        User user = null;
        UserAccount tbManagerUser = tbUserDao.find(username);
        if (tbManagerUser != null) {
            user = convertToUser(tbManagerUser);
        }
        
        UserRoleGroup userRoleGroup= getUserRoleGroupByUesrId(user.getId());        
        user.setUserRoleGroup(userRoleGroup);
        return user;
    }

    public User get(int id) {
        User user = null;
        UserAccount tbManagerUser = tbUserDao.find(id);
        if (tbManagerUser != null) {
            user = convertToUser(tbManagerUser);
        }
        return user;
    }

    public User login(String username, String password) {
        User user = null;
        UserAccount tbUser = tbUserDao.find(username);
        if (null != tbUser) {
            if (tbUser.getPassword().equals(password)) {
                logger.info("Password Ok!");
                user = convertToUser(tbUser);
            }
        }
        return user;
    }

    @SuppressWarnings("unchecked")
    public void queryUserList(UserQuery userquery) {
        Collection<User> userlist = new ArrayList<User>();
        StringBuilder hql = new StringBuilder();
        hql.append("from UserAccount t ");
        if (!StringUtils.isEmpty(userquery.getUsername())) {
            hql.append(" where t.username like '%" + userquery.getUsername()
                    + "%'");
        }
        Query query = tbUserDao.getHibernateSession().createQuery(
                hql.toString());
        if (userquery.getPagerCount() == -1) {
            userquery.setPagerCount(query.list().size());
        }

        query.setFirstResult(userquery.getPagerOffset());
        query.setMaxResults(userquery.getPagerPerPage());

        for (Iterator it = query.iterate(); it.hasNext();) {
            userlist.add(convertToUser((UserAccount) it.next()));
        }

        userquery.setQueryResults(userlist);
    }

    public void add(User user) {
        tbUserDao.create(convertToTbUser(user));
    }

    public void delete(int[] ids) {
        for (int id : ids) {
            tbUserDao.delete(id);
        }
    }

    public void modify(User user, User byuser) {
        user.setLastUpdateTs(new Date());
        user.setLastUpdateBy(byuser.getUsername());
        if (tbUserDao.find(user.getId()) != null) {
            tbUserDao.update(convertToTbUser(user));
        }
    }

    /**
     * @param tbUser TbUser(po)
     * @return User User(vo)
     */
    public User convertToUser(UserAccount tbUser) {
        User user = new User();
        BeanConverter.copyProperties(user, tbUser);
        if (!StringUtils.isEmpty(tbUser.getRolename())) {
            Collection<String> rolenames = new ArrayList<String>();
            if (roleMap != null && roleMap.containsKey(tbUser.getRolename())) {
                rolenames.add(roleMap.get(tbUser.getRolename()));
            } else {
                rolenames.add(tbUser.getRolename());
            }
            user.setRolenames(rolenames);
        }

        return user;
    }

    /**
     * @param user
     * @return
     */
    public UserAccount convertToTbUser(User user) {
        UserAccount tuser = new UserAccount();
        BeanConverter.copyProperties(tuser, user);
        if (null != user.getRolenames() && !user.getRolenames().isEmpty()) {
            for (String rolename : user.getRolenames()) {
                tuser.setRolename(rolename);
            }
        }
        return tuser;
    }

    /**
     * 
     */
    public void grant(User user, User byuser) {
        user.setLastUpdateTs(new Date());
        user.setLastUpdateBy(byuser.getUsername());
        if (tbUserDao.find(user.getId()) != null) {
            tbUserDao.update(convertToTbUser(user));
        }
    }

    /**
     * 
     */
    public void grantRoleGroup(UserRoleGroup pUserRoleGroup) {
        Session session = tbUserDao.getHibernateSession();
        session.saveOrUpdate(pUserRoleGroup);
    }

    /**
     * 
     */
    public UserRoleGroup getUserRoleGroupByUesrId(Integer userId) {
        Session session = tbUserDao.getHibernateSession();
        Query query =session.createQuery("select t from UserRoleGroup t where t.idUser =:idUser");
        query.setParameter("idUser", userId);
        
        return (UserRoleGroup) query.uniqueResult();
    }

    /**
     * 
     * @return
     */
    public List<RoleGroup> findAllRoleGroup() {
        return this.tbUserDao.findAllRoleGroup();
    }

    public void testLeftJoin() {
        Session session = this.tbUserDao.getHibernateSession();
        Query query = session.createQuery(" from Child c left join c.father");
        List<Object[]> list = query.list();

        for (Object[] obj : list) {
            Child child = (Child) obj[0];
            Father father = (Father) obj[1];
            System.out.println(child.getChildName());
            System.out.println(father.getName());
        }
    }

    public void setRoleMap(Map<String, String> roleMap) {
        this.roleMap = roleMap;
    }

    public Map<String, String> getRoleMap() {
        return roleMap;
    }

    public void setTbUserDao(TbUserDao pTbUserDao) {
        tbUserDao = pTbUserDao;
    }

}
